

/*******************************************************************
 *
 * Copyright (C), 2018-2018, www.letstrong.cn, All rights reserved.
 *
 * Author	   : xiaoyu | xiaoyu_ebox@163.com
 * Create Time : 2018-6-4
 * Version	   : v0.1
 * Description : ugui header file

 *	Mar 18, 2015  V0.3	Driver support added.
 *						Window and object support added.
 *						Touch support added.
 *						Fixed some minor bugs.
 *
 *	Oct 20, 2014  V0.2	Function UG_DrawRoundFrame() added.
 *						Function UG_FillRoundFrame() added.
 *						Function UG_DrawArc() added.
 *						Fixed some minor bugs.
 *
 *	Oct 11, 2014  V0.1	First release.
 *******************************************************************/
#ifndef __UGUI_H__
#define __UGUI_H__

#ifdef __cplusplus
extern "C"
{
#endif

/*----------------------------Head file----------------------------*/
#include "ugui_config.h"
#include "ugui_types.h"
#include "ugui_font.h"
#include "ugui_color.h"
#include "ugui_define.h"

/*----------------------------macro file---------------------------*/

/*----------------------------type define--------------------------*/
typedef struct S_BMP UG_BMP;
typedef struct S_OBJECT UG_OBJECT;
typedef struct S_WINDOW UG_WINDOW;
typedef UG_S8 UG_RESULT;

#if (CONFIG_GUI_COLOR == USE_COLOR_RGB565)
typedef UG_U16 UG_COLOR;
#else // USE_COLOR_RGB888/USE_COLOR_ARGB8888
typedef UG_U32 UG_COLOR;
#endif


typedef UG_U8 *(*malloc_buffer_callback) (UG_U32 size);
typedef void (*draw_pixel_driver_callback)(UG_S16 x, UG_S16 y, UG_COLOR c);
#if (CONFIG_UI_BUFFER == UI_BUFFER_NONE)
typedef void(*update_event_callback) (UG_U8 event);
#else
typedef void(*update_buffer_callback) (UG_U8 *buffer, UG_U16 w, UG_U16 h);
#endif

typedef struct {
	UG_S16 xs;
	UG_S16 ys;
	UG_S16 xe;
	UG_S16 ye;
} UG_AREA;


typedef struct {
	char * str;
	const UG_FONT * font;
	UG_AREA a;
	UG_COLOR fc;
	UG_COLOR bc;
	UG_U8 align;
	UG_S16 h_space;
	UG_S16 v_space;
} UG_TEXT;


struct S_BMP {
	void * p;
	UG_U16 width;
	UG_U16 height;
	UG_U8 bpp;
	UG_U8 colors;
};


/* Message structure */
typedef struct {
	UG_U8 type;
	UG_U8 id;
	UG_U8 sub_id;
	UG_U8 event;
	void * src;
} UG_MESSAGE;


/* Touch structure */
typedef struct {
	UG_U8 state;
	UG_S16 xp;
	UG_S16 yp;
} UG_TOUCH;


/* Object structure */
struct S_OBJECT {
	UG_U8 state;								/* object state 							  */
	UG_U8 touch_state;							/* object touch state						  */
	void(*update) (UG_WINDOW *, UG_OBJECT *);	/* pointer to object-specific update function */
	UG_AREA a_abs;								/* absolute area of the object				  */
	UG_AREA a_rel;								/* relative area of the object				  */
	UG_U8 type; 								/* object type								  */
	UG_U8 id;									/* object ID								  */
	UG_U8 event;								/* object-specific events					  */
	void * data;								/* pointer to object-specific data			  */
};


/* object types */
typedef enum {
	OBJ_TYPE_NONE = 0, 
		OBJ_TYPE_BUTTON, 
		OBJ_TYPE_TEXTBOX, 
		OBJ_TYPE_IMAGE, 
		OBJ_TYPE_CHECKBOX
} OBJECTS_TYPE_T;


/* Title structure */
typedef struct {
	char * str;
	const UG_FONT * font;
	UG_S8 h_space;
	UG_S8 v_space;
	UG_U8 align;
	UG_COLOR fc;		// 激活时的前景色
	UG_COLOR bc;		// 激活时的背景色
	UG_COLOR ifc;		// 失效时的前景色
	UG_COLOR ibc;		// 失效时的背景色
	UG_U8 height;
} UG_TITLE;


/* Window structure */
struct S_WINDOW {
	UG_U8 objcnt;
	UG_OBJECT * objlst;
	UG_U8 state;
	UG_COLOR fc;
	UG_COLOR bc;
	UG_AREA a;
	UG_U8 style;
	UG_TITLE title;
	void(*cb) (UG_MESSAGE *);
};


/* Button structure */
typedef struct {
	UG_U8 state;
	UG_U8 style;
	UG_COLOR fc;
	UG_COLOR bc;
	UG_COLOR afc;
	UG_COLOR abc;
	const UG_FONT * font;
	UG_U8 align;
	UG_S8 h_space;
	UG_S8 v_space;
	char * str;
} UG_BUTTON;


/* Checkbox structure */
typedef struct {
	UG_U8 state;
	UG_U8 style;
	UG_COLOR fc;
	UG_COLOR bc;
	UG_COLOR afc;
	UG_COLOR abc;
	const UG_FONT * font;
	UG_U8 align;
	UG_S8 h_space;
	UG_S8 v_space;
	char * str;
	UG_U8 checked;
} UG_CHECKBOX;


/* Textbox structure */
typedef struct {
	char * str;
	const UG_FONT * font;
	UG_U8 style;
	UG_COLOR fc;
	UG_COLOR bc;
	UG_U8 align;
	UG_S8 h_space;
	UG_S8 v_space;
} UG_TEXTBOX;


/* Image structure */
typedef struct {
	void * img;
	UG_U8 type;
	UG_U8 effect;		// 0:静态 >0:动画效果
	bool  draw_over;
} UG_IMAGE;


/* driver structure */
typedef struct {
	void * driver;
	UG_U8 state;
} UG_DRIVER;


/* CORE STRUCTURE */
typedef struct {
	UG_S16 w_dim;								// 物理宽度
	UG_S16 h_dim;								// 物理高度
	UG_TOUCH touch; 							// 触摸信息
	UG_WINDOW * next_window;
	UG_WINDOW * active_window;					// 当前激活的窗口
	UG_WINDOW * last_window;

	struct {
		UG_AREA a;
		UG_S16 x_pos;
		UG_S16 y_pos;
		UG_COLOR fore_color;
		UG_COLOR back_color;
	} console;

	UG_FONT font;
	UG_S8 char_h_space;
	UG_S8 char_v_space;
	UG_COLOR fore_color;
	UG_COLOR back_color;
	UG_COLOR desktop_color;
	UG_U8 state;
	UG_DRIVER driver[NUMBER_OF_DRIVERS];

	bool has_update;
#if (CONFIG_UI_BUFFER == UI_BUFFER_ONE)
	uint8 *g_current_fbuffer;
#elif (CONFIG_UI_BUFFER == UI_BUFFER_THREE)
	uint8 *g_current_fbuffer;
	uint8 *g_temp_fbuffer;
	uint8 *g_prev_fbuffer;
	uint8 *g_mid_fbuffer;
	uint8 *g_next_fbuffer;

	UG_U8 direction;
	bool  switching;
#endif
} UG_GUI;


/*-----------------------------------------------------------------*/
UG_RESULT UG_Init(UG_GUI * g, malloc_buffer_callback cb);
void UG_SelectGUI(UG_GUI * g);
void UG_FontSelect(const UG_FONT * font);
void UG_FillScreen(UG_COLOR c);
void UG_FillFrame(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_COLOR c);
void UG_FillRoundFrame(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_S16 r, UG_COLOR c);
void UG_DrawMesh(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_COLOR c);
void UG_DrawFrame(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_COLOR c);
void UG_DrawRoundFrame(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_S16 r, UG_COLOR c);
void UG_DrawPixel(UG_S16 x0, UG_S16 y0, UG_COLOR c);
void UG_DrawCircle(UG_S16 x0, UG_S16 y0, UG_S16 r, UG_COLOR c);
void UG_FillCircle(UG_S16 x0, UG_S16 y0, UG_S16 r, UG_COLOR c);
void UG_DrawArc(UG_S16 x0, UG_S16 y0, UG_S16 r, UG_U8 s, UG_COLOR c);
void UG_DrawLine(UG_S16 x1, UG_S16 y1, UG_S16 x2, UG_S16 y2, UG_COLOR c);
void UG_PutString(UG_S16 x, UG_S16 y, char * str);
void UG_PutChar(char chr, UG_S16 x, UG_S16 y, UG_COLOR fc, UG_COLOR bc);
void UG_ConsolePutString(char * str);
void UG_ConsoleSetArea(UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
void UG_ConsoleSetForecolor(UG_COLOR c);
void UG_ConsoleSetBackcolor(UG_COLOR c);
void UG_SetForecolor(UG_COLOR c);
void UG_SetBackcolor(UG_COLOR c);
UG_S16 UG_GetXDim(void);
UG_S16 UG_GetYDim(void);
void UG_FontSetHSpace(UG_U16 s);
void UG_FontSetVSpace(UG_U16 s);

/* Miscellaneous functions */
void UG_WaitForUpdate(void);
void UG_Update(void);
void UG_DrawBMP(UG_S16 xp, UG_S16 yp, UG_BMP * bmp);
void UG_TouchUpdate(UG_S16 xp, UG_S16 yp, UG_U8 state);

/* Driver functions */
void UG_DriverRegister(UG_U8 type, void * driver);
void UG_DriverEnable(UG_U8 type);
void UG_DriverDisable(UG_U8 type);

/* Window functions */
UG_RESULT UG_WindowCreate(UG_WINDOW * wnd, UG_OBJECT * objlst, UG_U8 objcnt, void(*cb) (UG_MESSAGE *));
UG_RESULT UG_WindowDelete(UG_WINDOW * wnd);
UG_RESULT UG_WindowShow(UG_WINDOW * wnd);
UG_RESULT UG_WindowHide(UG_WINDOW * wnd);
UG_RESULT UG_WindowResize(UG_WINDOW * wnd, UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
UG_RESULT UG_WindowAlert(UG_WINDOW * wnd);
UG_RESULT UG_WindowSetForeColor(UG_WINDOW * wnd, UG_COLOR fc);
UG_RESULT UG_WindowSetBackColor(UG_WINDOW * wnd, UG_COLOR bc);
UG_RESULT UG_WindowSetTitleTextColor(UG_WINDOW * wnd, UG_COLOR c);
UG_RESULT UG_WindowSetTitleColor(UG_WINDOW * wnd, UG_COLOR c);
UG_RESULT UG_WindowSetTitleInactiveTextColor(UG_WINDOW * wnd, UG_COLOR c);
UG_RESULT UG_WindowSetTitleInactiveColor(UG_WINDOW * wnd, UG_COLOR c);
UG_RESULT UG_WindowSetTitleText(UG_WINDOW * wnd, char * str);
UG_RESULT UG_WindowSetTitleTextFont(UG_WINDOW * wnd, const UG_FONT * font);
UG_RESULT UG_WindowSetTitleTextHSpace(UG_WINDOW * wnd, UG_S8 hs);
UG_RESULT UG_WindowSetTitleTextVSpace(UG_WINDOW * wnd, UG_S8 vs);
UG_RESULT UG_WindowSetTitleTextAlignment(UG_WINDOW * wnd, UG_U8 align);
UG_RESULT UG_WindowSetTitleHeight(UG_WINDOW * wnd, UG_U8 height);
UG_RESULT UG_WindowSetXStart(UG_WINDOW * wnd, UG_S16 xs);
UG_RESULT UG_WindowSetYStart(UG_WINDOW * wnd, UG_S16 ys);
UG_RESULT UG_WindowSetXEnd(UG_WINDOW * wnd, UG_S16 xe);
UG_RESULT UG_WindowSetYEnd(UG_WINDOW * wnd, UG_S16 ye);
UG_RESULT UG_WindowSetStyle(UG_WINDOW * wnd, UG_U8 style);
UG_COLOR UG_WindowGetForeColor(UG_WINDOW * wnd);
UG_COLOR UG_WindowGetBackColor(UG_WINDOW * wnd);
UG_COLOR UG_WindowGetTitleTextColor(UG_WINDOW * wnd);
UG_COLOR UG_WindowGetTitleColor(UG_WINDOW * wnd);
UG_COLOR UG_WindowGetTitleInactiveTextColor(UG_WINDOW * wnd);
UG_COLOR UG_WindowGetTitleInactiveColor(UG_WINDOW * wnd);
char * UG_WindowGetTitleText(UG_WINDOW * wnd);
UG_FONT * UG_WindowGetTitleTextFont(UG_WINDOW * wnd);
UG_S8 UG_WindowGetTitleTextHSpace(UG_WINDOW * wnd);
UG_S8 UG_WindowGetTitleTextVSpace(UG_WINDOW * wnd);
UG_U8 UG_WindowGetTitleTextAlignment(UG_WINDOW * wnd);
UG_U8 UG_WindowGetTitleHeight(UG_WINDOW * wnd);
UG_S16 UG_WindowGetXStart(UG_WINDOW * wnd);
UG_S16 UG_WindowGetYStart(UG_WINDOW * wnd);
UG_S16 UG_WindowGetXEnd(UG_WINDOW * wnd);
UG_S16 UG_WindowGetYEnd(UG_WINDOW * wnd);
UG_U8 UG_WindowGetStyle(UG_WINDOW * wnd);
UG_RESULT UG_WindowGetArea(UG_WINDOW * wnd, UG_AREA * a);
UG_S16 UG_WindowGetInnerWidth(UG_WINDOW * wnd);
UG_S16 UG_WindowGetOuterWidth(UG_WINDOW * wnd);
UG_S16 UG_WindowGetInnerHeight(UG_WINDOW * wnd);
UG_S16 UG_WindowGetOuterHeight(UG_WINDOW * wnd);

/* Button functions */
UG_RESULT UG_ButtonCreate(UG_WINDOW * wnd, UG_BUTTON * btn, UG_U8 id, UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
UG_RESULT UG_ButtonDelete(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_ButtonShow(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_ButtonHide(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_ButtonSetForeColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR fc);
UG_RESULT UG_ButtonSetBackColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR bc);
UG_RESULT UG_ButtonSetAlternateForeColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR afc);
UG_RESULT UG_ButtonSetAlternateBackColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR abc);
UG_RESULT UG_ButtonSetText(UG_WINDOW * wnd, UG_U8 id, char * str);
UG_RESULT UG_ButtonSetFont(UG_WINDOW * wnd, UG_U8 id, const UG_FONT * font);
UG_RESULT UG_ButtonSetStyle(UG_WINDOW * wnd, UG_U8 id, UG_U8 style);
UG_RESULT UG_ButtonSetHSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 hs);
UG_RESULT UG_ButtonSetVSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 vs);
UG_RESULT UG_ButtonSetAlignment(UG_WINDOW * wnd, UG_U8 id, UG_U8 align);
UG_COLOR UG_ButtonGetForeColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_ButtonGetBackColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_ButtonGetAlternateForeColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_ButtonGetAlternateBackColor(UG_WINDOW * wnd, UG_U8 id);
char * UG_ButtonGetText(UG_WINDOW * wnd, UG_U8 id);
UG_FONT * UG_ButtonGetFont(UG_WINDOW * wnd, UG_U8 id);
UG_U8 UG_ButtonGetStyle(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_ButtonGetHSpace(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_ButtonGetVSpace(UG_WINDOW * wnd, UG_U8 id);
UG_U8 UG_ButtonGetAlignment(UG_WINDOW * wnd, UG_U8 id);


/* Checkbox functions */
UG_RESULT UG_CheckboxCreate(UG_WINDOW * wnd, UG_CHECKBOX * btn, UG_U8 id, UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
UG_RESULT UG_CheckboxDelete(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_CheckboxShow(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_CheckboxHide(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_CheckboxSetCheched(UG_WINDOW * wnd, UG_U8 id, UG_U8 ch);
UG_RESULT UG_CheckboxSetForeColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR fc);
UG_RESULT UG_CheckboxSetBackColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR bc);
UG_RESULT UG_CheckboxSetAlternateForeColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR afc);
UG_RESULT UG_CheckboxSetAlternateBackColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR abc);
UG_RESULT UG_CheckboxSetText(UG_WINDOW * wnd, UG_U8 id, char * str);
UG_RESULT UG_CheckboxSetFont(UG_WINDOW * wnd, UG_U8 id, const UG_FONT * font);
UG_RESULT UG_CheckboxSetStyle(UG_WINDOW * wnd, UG_U8 id, UG_U8 style);
UG_RESULT UG_CheckboxSetHSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 hs);
UG_RESULT UG_CheckboxSetVSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 vs);
UG_RESULT UG_CheckboxSetAlignment(UG_WINDOW * wnd, UG_U8 id, UG_U8 align);
UG_U8 UG_CheckboxGetChecked(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_CheckboxGetForeColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_CheckboxGetBackColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_CheckboxGetAlternateForeColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_CheckboxGetAlternateBackColor(UG_WINDOW * wnd, UG_U8 id);
char * UG_CheckboxGetText(UG_WINDOW * wnd, UG_U8 id);
UG_FONT * UG_CheckboxGetFont(UG_WINDOW * wnd, UG_U8 id);
UG_U8 UG_CheckboxGetStyle(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_CheckboxGetHSpace(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_CheckboxGetVSpace(UG_WINDOW * wnd, UG_U8 id);
UG_U8 UG_CheckboxGetAlignment(UG_WINDOW * wnd, UG_U8 id);



/* Textbox functions */
UG_RESULT UG_TextboxCreate(UG_WINDOW * wnd, UG_TEXTBOX * txb, UG_U8 id, UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
UG_RESULT UG_TextboxDelete(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_TextboxShow(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_TextboxHide(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_TextboxSetForeColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR fc);
UG_RESULT UG_TextboxSetBackColor(UG_WINDOW * wnd, UG_U8 id, UG_COLOR bc);
UG_RESULT UG_TextboxSetText(UG_WINDOW * wnd, UG_U8 id, char * str);
UG_RESULT UG_TextboxSetFont(UG_WINDOW * wnd, UG_U8 id, const UG_FONT * font);
UG_RESULT UG_TextboxSetHSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 hs);
UG_RESULT UG_TextboxSetVSpace(UG_WINDOW * wnd, UG_U8 id, UG_S8 vs);
UG_RESULT UG_TextboxSetAlignment(UG_WINDOW * wnd, UG_U8 id, UG_U8 align);
UG_COLOR UG_TextboxGetForeColor(UG_WINDOW * wnd, UG_U8 id);
UG_COLOR UG_TextboxGetBackColor(UG_WINDOW * wnd, UG_U8 id);
char * UG_TextboxGetText(UG_WINDOW * wnd, UG_U8 id);
UG_FONT * UG_TextboxGetFont(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_TextboxGetHSpace(UG_WINDOW * wnd, UG_U8 id);
UG_S8 UG_TextboxGetVSpace(UG_WINDOW * wnd, UG_U8 id);
UG_U8 UG_TextboxGetAlignment(UG_WINDOW * wnd, UG_U8 id);

/* Image functions */
UG_RESULT UG_ImageCreate(UG_WINDOW * wnd, UG_IMAGE * img, UG_U8 id, UG_S16 xs, UG_S16 ys, UG_S16 xe, UG_S16 ye);
UG_RESULT UG_ImageDelete(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_ImageShow(UG_WINDOW * wnd, UG_U8 id, UG_U8 effect);
UG_RESULT UG_ImageHide(UG_WINDOW * wnd, UG_U8 id);
UG_RESULT UG_ImageSetBMP(UG_WINDOW * wnd, UG_U8 id, const UG_BMP * bmp);


bool UG_SwitchPanel(UG_U8 direction);



#ifdef __cplusplus
}


#endif

#endif // __UGUI_H__

